package com.gjintel.framework.dept.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gjintel.framework.cache.InitCacheData;
import com.gjintel.framework.cache.InitCacheData.CacheType;
import com.gjintel.framework.dept.dao.IDeptDao;
import com.gjintel.framework.dept.model.Dept;
import com.gjintel.framework.dept.service.IDeptService;
import com.gjintel.framework.log.model.LogInfo;
import com.gjintel.framework.log.util.LogUtil;
import com.gjintel.framework.log.util.LogUtil.LogType;
import com.gjintel.framework.user.model.User;
import com.gjintel.framework.util.CommUtil;
import com.gjintel.sdk.base.dao.Page;
import com.gjintel.sdk.base.dao.Sort;
import com.gjintel.sdk.base.service.impl.BaseServiceImpl;
import com.gjintel.sdk.dto.TreeDto;
import com.gjintel.sdk.util.StringUtil;

@Service("deptService")
public class DeptServiceImpl extends BaseServiceImpl implements IDeptService {
	@Autowired
	private IDeptDao deptDao;

	@SuppressWarnings("unchecked")
	public List<String> getDeptTree(List<TreeDto> treeList, String id, String nodeName, String selectIds, boolean isUserTree,boolean isRoot,boolean isManager) {
		List<String> selIds = new ArrayList<String>();
		Map<String, List> deptTreeData = InitCacheData.getInstance().getCacheTreeData(InitCacheData.CacheType.DEPT);
		if (deptTreeData != null) {
			if (StringUtil.isEmpty(id)) {
				id = InitCacheData.ROOT;
			}
			if (StringUtil.isEmpty(nodeName) && StringUtil.isEmpty(selectIds)) {
				if(isRoot){
					if("root".equals(id)){
						id="1";
					}
					TreeDto treeDto = this.getTreeNode((Dept)(InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.DEPT).get(id)));
					treeDto.setChildren(this.getTreePoints(deptTreeData, id, isUserTree,isManager));
					treeList.add(treeDto);
				} else {
					List<TreeDto> rootTreeList = this.getTreePoints(deptTreeData, id, isUserTree,isManager);
					treeList.addAll(rootTreeList);
				}
			} else {
				// 根据查询信息，查询机构数据，并显示
				if(isRoot){
					if(isManager){
						List<TreeDto> rootTreeList = this.getTreePoints(deptTreeData, id, isUserTree,isManager);
						TreeDto rootTree = null;
						if (rootTreeList != null && rootTreeList.size() == 1) {
							rootTree = rootTreeList.get(0);
							rootTree.setState("open");
							treeList.add(rootTree);
							this.getSelectMenuTree(rootTree, rootTree, nodeName, selectIds, selIds, isUserTree,isManager);
						}
					} else {
						TreeDto treeDto = this.getTreeNode((Dept)(InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.DEPT).get(id)));
						treeList.add(treeDto);
						this.getSelectMenuTree(treeDto, treeDto, nodeName, selectIds, selIds, isUserTree,isManager);
					}
				} 
//				
			}
		}
		return selIds;
	}

	/**
	 * @description 根据当前的节点逐层判断它的上级节点可是跟节点，如果不是，把该节点进行张开
	 * @author fengya
	 * @date 2015-7-30 下午04:45:13
	 * @param id
	 *            被选中的节点ID
	 * @param rootNode
	 *            根节点
	 * @return void
	 */
	private void setNodeOpen(String id, TreeDto rootNode) {
		if (id != null && !id.trim().equals(InitCacheData.ROOT)) {
			Map<String, Object> postMap = InitCacheData.getInstance().getCacheData(CacheType.DEPT);
			Object obj = postMap.get(id);
			if (obj != null) {
				Dept dept = (Dept) obj;
				// 得到树中对应ID的节点
				this.getNode(rootNode, dept.getPid());
				this.setNodeOpen(dept.getPid(), rootNode);
			}
		}
	}

	/**
	 * @description 展开根节点的ID
	 * @author fengya
	 * @date 2015-7-30 下午04:46:24
	 * @param node
	 * @param pid
	 * @return void
	 */
	private void getNode(TreeDto node, String pid) {
		if (node.getId().trim().equals(pid)) {
			node.setState(TreeDto.stateValue.OPEN.toString().toLowerCase());
		} else {
			Iterator<TreeDto> nodeIt = node.getChildren().iterator();
			while (nodeIt.hasNext()) {
				this.getNode(nodeIt.next(), pid);
			}
		}
	}

	/**
	 * @description 得到节点下的菜单进行回显和查询
	 * @author fengya
	 * @date 2015-7-30 下午05:01:40
	 * @param node
	 * @param rootNode
	 * @param nodeName
	 * @param selectIds
	 * @param selIds
	 * @param isDeptTree
	 * @return void
	 */
	private void getSelectMenuTree(TreeDto node, TreeDto rootNode, String nodeName, String selectIds, List<String> selIds, boolean isUserTree,boolean isManager) {
		if (!StringUtil.isEmpty(selectIds)) {
			String[] selectId = selectIds.split(",");
			if (CommUtil.contains(selectId, node.getId())) {
				node.setChecked(true);
				this.setNodeOpen(node.getId(), rootNode);
			}
		}
		if (!StringUtil.isEmpty(nodeName) && node.getText().trim().contains(nodeName)) {
			// 找到查询的节点后，进行处理
			selIds.add(node.getId());
			// 遍历树，把查询后的节点对应的父节点全部展开
			this.setNodeOpen(node.getId(), rootNode);
		}
		// 遍历树的孩子节点
		List<TreeDto> childrens = this.getTreePoints(InitCacheData.getInstance().getCacheTreeData(InitCacheData.CacheType.DEPT), node.getId(), isUserTree,isManager);
		node.setChildren(childrens);
		Iterator<TreeDto> nodeIt = childrens.iterator();
		while (nodeIt.hasNext()) {
			// 递归调用孩子中的每个节点
			this.getSelectMenuTree(nodeIt.next(), rootNode, nodeName, selectIds, selIds, isUserTree,isManager);
		}
	}
	
	/**
	 * @description 得到树的根节点，并设置是打开状态
	 * @author fengya
	 * @date 2016-4-25 上午09:57:52
	 * @param dept
	 * @return
	 * @return TreeDto
	 */
	private TreeDto getTreeNode(Dept dept){
		TreeDto treeDto = null;
		treeDto = new TreeDto();
		treeDto.setIconCls("icon-dept-menu");
		treeDto.setId(dept.getId());
		treeDto.setText(dept.getName());
		treeDto.setChildren(new ArrayList<TreeDto>());
		treeDto.setState("open");
		return treeDto;
	}

	@SuppressWarnings("unchecked")
	private List<TreeDto> getTreePoints(Map<String, List> childrenDeptList, String id, boolean isUserTree,boolean isManager) {
		List<Dept> childrenDept = childrenDeptList.get(id);
		List<TreeDto> treeList = new ArrayList<TreeDto>();
		if (childrenDept != null && !childrenDept.isEmpty()) {
			TreeDto treeDto = null;
			Dept dept = null;
			Iterator<Dept> deptIt = childrenDept.iterator();
			while (deptIt.hasNext()) {
				dept = deptIt.next();
				if(!isManager){
					if(!"3".equals(dept.getType())){
						continue;
					}
				}
				treeDto = new TreeDto();
				treeDto.setIconCls("icon-dept-menu");
				treeDto.setId(dept.getId());
				treeDto.setText(dept.getName());
				if (isUserTree) {
					treeDto.setState("closed");
				} else {
					if (InitCacheData.getInstance().getCacheTreeData(InitCacheData.CacheType.DEPT).get(treeDto.getId()) != null) {
						treeDto.setChildren(new ArrayList<TreeDto>());
						treeDto.setState("closed");
					}
				}
				treeList.add(treeDto);
			}
		}
		return treeList;
	}

	@SuppressWarnings("unchecked")
	public void findAll(Page page, Dept dept, Sort sort,int loginUserType,String loginUserDeptUnit,String deptId) {
		this.deptDao.findAll(page, dept, sort,loginUserType,loginUserDeptUnit,deptId);
		Dept temp = null;
		Iterator<Dept> deptIt = page.getResult().iterator();
		while (deptIt.hasNext()) {
			temp = deptIt.next();
			if (temp.getPid() != null) {
				Object obj = InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.DEPT).get(temp.getPid());
				if (obj != null) {
					temp.setpName(((Dept) (obj)).getName());
				}
			}
			if (temp.getpUnit() != null){
				Object obj = InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.DEPT).get(temp.getpUnit());
				if (obj != null) {
					temp.setpUnitName(((Dept) (obj)).getName());
				}
			}
		}
	}

	@Override
	public void removeData(String deleteIds,User user) {
		Dept dept = null;
		for (String id : deleteIds.split(",")) {
			dept = this.get(Dept.class, id);
			if (dept != null) {
				dept.setFlag(1);
				LogUtil.addLog(new LogInfo("删除部门信息", user.getId(), user.getName(), String.valueOf(LogType.DELETE.ordinal()), Dept.class.getSimpleName(), id));
			}
		}
	}

	@Override
	public List<Dept> findAll() {
		return this.deptDao.findAll();
	}

	@SuppressWarnings("unchecked")
//	public List<String> getUserTree(List<TreeDto> treeList, String id, String nodeName, String selectIds) {
//		this.getDeptTree(treeList, id, nodeName, selectIds, true,false);
//		List<String> selIds = new ArrayList<String>();
//		Object obj = InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.USER);
//		if (obj != null) {
//			Map<String, User> userMap = (Map<String, User>) obj;
//			if (!StringUtil.isEmpty(id)) {
//				treeList.addAll(this.getUserChildrens(userMap, id));
//			} else {
//				if (nodeName == null && StringUtil.isEmpty(selectIds)) {
//					treeList.get(0).getChildren().addAll(this.getUserChildrens(userMap, treeList.get(0).getId()));
//				} else {
//					Object deptObj = InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.DEPT);
//					Map<String, Dept> deptMap = (Map<String, Dept>) deptObj;
//					this.getSelectUserTree(treeList.get(0), treeList.get(0), deptMap, userMap, nodeName, selectIds, selIds, true);
//				}
//
//			}
//		}
//		return selIds;
//	}

	/**
	 * @方法名：getSelectUserTree
	 * @功能说明：根据查询名称，查询树中所有的人员信息
	 * @author fengya
	 * @date 2014-4-26 下午03:53:04
	 * @param node
	 *            ： 查询的节点
	 * @param rootNode
	 *            ： 树的根节点
	 * @param deptMap
	 *            ： 机构缓存数据
	 * @param userMap
	 *            ： 用户缓存数据
	 * @param nodeName
	 *            ： 查询名称
	 * @param selIds
	 *            ： 查询得到的节点ID集合
	 * @param isDeptTree
	 *            ： 是否是机构查询
	 * @return void
	 */
	private void getSelectUserTree(TreeDto node, TreeDto rootNode, Map<String, Dept> deptMap, Map<String, User> userMap, String nodeName, String selectIds, List<String> selIds,
			boolean isDeptTree) {
		if (!StringUtil.isEmpty(selectIds)) {
			String[] selectId = selectIds.split(",");
			if (node.isLeaf() && ArrayUtils.contains(selectId, node.getId())) {
				node.setChecked(true);
				this.setUserNodeOpen(userMap.get(node.getId()).getDeptId(), deptMap, rootNode);
			}
		}
		if (!StringUtil.isEmpty(nodeName) && node.isLeaf() && node.getText().trim().contains(nodeName)) {
			selIds.add(node.getId());
			this.setUserNodeOpen(userMap.get(node.getId()).getDeptId(), deptMap, rootNode);
		}
		List<TreeDto> childrens = node.getChildren();
		if(!childrens.isEmpty()){
			List<TreeDto> userChildrens = this.getUserChildrens(userMap, node.getId());
			childrens.addAll(userChildrens);
			node.setChildren(childrens);
			Iterator<TreeDto> nodeIt = childrens.iterator();
			while (nodeIt.hasNext()) {
				this.getSelectUserTree(nodeIt.next(), rootNode, deptMap, userMap, nodeName, selectIds, selIds, isDeptTree);
			}
		}
		
	}

	/**
	 * @方法名：setUserNodeOpen
	 * @功能说明：根据ID得到机构信息，并遍历所有的父节点进行更改状态
	 * @author fengya
	 * @date 2014-4-26 下午03:49:24
	 * @param id
	 *            : 节点ID
	 * @param deptMap
	 *            ： 机构缓存数据
	 * @param rootNode
	 *            ： 树根节点
	 * @return void
	 */
	private void setUserNodeOpen(String id, Map<String, Dept> deptMap, TreeDto rootNode) {
		if (id != null && !id.trim().equals(InitCacheData.ROOT)) {
			Dept dept = deptMap.get(id);
			this.getUserNode(rootNode, id);
			this.setUserNodeOpen(dept.getPid(), deptMap, rootNode);
		}
	}

	/**
	 * @方法名：getUserNode
	 * @功能说明：遍历找到树中所有的父节点，并更改为展开状态
	 * @author fengya
	 * @date 2014-4-26 下午03:50:49
	 * @param node
	 *            ： 遍历的节点
	 * @param pid
	 *            ： 遍历节点的父ID
	 * @return void
	 */
	private void getUserNode(TreeDto node, String pid) {
		if (node.getId().trim().equals(pid)) {
			node.setState(TreeDto.stateValue.OPEN.toString().toLowerCase());
		} else {
			Iterator<TreeDto> nodeIt = node.getChildren().iterator();
			while (nodeIt.hasNext()) {
				this.getUserNode(nodeIt.next(), pid);
			}
		}
	}

	/**
	 * @方法名：getUserChildrens
	 * @功能说明：得到机构下所有人员的信息，并转变成树节点
	 * @author fengya
	 * @date 2014-4-26 下午03:56:22
	 * @param userMap
	 *            ： 人员缓存数据
	 * @param id
	 *            ： 父节点的ID
	 * @return
	 * @return List<TreeDto>
	 */
	private List<TreeDto> getUserChildrens(Map<String, User> userMap, String id) {
		List<TreeDto> childrens = new ArrayList<TreeDto>();
		Collection<User> userSet = userMap.values();
		Iterator<User> userIt = userSet.iterator();
		User user = null;
		Map<String, Object> deptMap = InitCacheData.getInstance().getCacheData(InitCacheData.CacheType.DEPT);
		Object obj = null;
		while (userIt.hasNext()) {
			user = userIt.next();
			if (!StringUtil.isEmpty(user.getDeptId()) && user.getDeptId().trim().equals(id)) {
				obj = deptMap.get(id);
				if (obj != null) {
					user.setDeptName(((Dept) obj).getName());
				}
				childrens.add(this.getTreeDto(user));
			}
		}
		return childrens;
	}

	/**
	 * @方法名：getTreeDto
	 * @功能说明：把人员信息展示在树节点中
	 * @author fengya
	 * @date 2014-4-26 下午03:55:47
	 * @param user
	 *            ：人员信息
	 * @return
	 * @return TreeDto
	 */
	private TreeDto getTreeDto(User user) {
		TreeDto dto = new TreeDto();
		dto.setExchangeInfo(user.getDeptName());
		dto.setId(user.getId());
		dto.setText(user.getName());
		dto.setIconCls("icon-user-icon");
		dto.setLeaf(true);
		return dto;
	}
}